package cn.com.vs.api;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import cn.com.vs.Configurator;
import cn.com.vs.model.ApplicationInfo;
import cn.com.vs.model.ApplicationList;
import cn.com.vs.model.ApplicationStatus;
import cn.com.vs.model.ContactItem;
import cn.com.vs.model.ContactList;
import cn.com.vs.model.GeneralJSONResult;
import cn.com.vs.model.ImageInfo;
import cn.com.vs.model.Position;
import cn.com.vs.model.Status;
import cn.com.vs.model.TalkDetails;
import cn.com.vs.model.UserTalks;
import cn.com.vs.service.CloudMapService;
import cn.com.vs.service.RedisService;
import cn.com.vs.service.StoreService;
import cn.com.vs.service.UserService;
import cn.com.vs.service.UserService.RetCode;
import cn.com.vs.service.domain.Comment;
import cn.com.vs.service.domain.Member;
import cn.com.vs.service.domain.Talk;
import cn.com.vs.service.domain.UserData;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.hash.Hashing;
import com.qiniu.util.Auth;

@Path("/api") 
public class UserApi {
	protected Logger logger = Logger.getLogger(getClass());
	public static int token_alive = 3600*24*30;
	/**
	 * 用户账户登录
	 * 
	 * @param account
	 * @param passwd
	 * @return
	 */
	@POST  
	@Path("/login")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public String userLogin(
			@FormParam("loginToken") String loginToken, 
			@FormParam("passwd") String passwd,
			@FormParam("type") String loginType)
	{
		GeneralJSONResult status = new GeneralJSONResult();
		if( StringUtils.isBlank(loginType) ){
			status.setOk(false);
			status.setMessage("登陆类型必须填写");
			return status.toString();
		}
		JSONObject ui = UserService.getInstance().userLogin(loginToken, passwd, loginType);
		if( ui == null ){
			status.setOk(false);
			status.setMessage("登陆失败，登陆信息不正确或用户不存在");
			return status.toString();
		}else{
			if( ui.containsKey("ok") && !ui.getBoolean("ok") ){
				status.setOk(false);
				status.setMessage(ui.getString("message"));
				return status.toString();
			}
			String account = ui.getString("account");
			if( StringUtils.isBlank(ui.getString("token")) ){
				//首次登录，无token
				generateUserToken(ui);
			}else{
				if( !ApiUtils.checkToken(ui.getString("token"), account) ){
					//token已经过期或丢失，重新生成
					RedisService.getInstance().delete(ui.getString("token"));
					generateUserToken(ui);
				}else{
					//更新token生命期
					RedisService.getInstance().expire(ui.getString("token"),token_alive);
				}
			}
			ui.put("ok", true);
		}
		return ui.toString();
	}

	
	/**
	 * 按类型登录，内部使用
	 * @param type
	 * @param value
	 * @param ctx
	 * @return
	 */
	@POST  
	@Path("/wechat/members")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public String wechatMembers(
			@FormParam("appid") String appid,
			@Context HttpServletRequest ctx)
	{
		GeneralJSONResult status = new GeneralJSONResult();
		if( StringUtils.isBlank(appid) ){
			status.setOk(false);
			status.setMessage("appid必须填写");
			return status.toString();
		}
		
		
		String addr = ctx.getRemoteAddr();
		JSONArray ls = Configurator.getInstance().getArray("safe_servers");
		if( ls != null ){
			if( !ls.contains( addr ) ){
				status.setOk(false);
				status.setMessage("非法访问");
				return status.toString();
			}
		}
		
		JSONArray result = UserService.getInstance().getWechatAppMembers(appid);
		if( result == null ){
			status.setOk(false);
			status.setMessage("获取成员列表失败");
			return status.toString();
		}else{
			status.setData( result );
			status.setOk( true );
		}
		return status.toString();
	}
	
	private String generateUserToken(JSONObject userInfo ){
		String userToken = Hashing.goodFastHash(32).hashBytes(userInfo.getString("account").getBytes()).toString();
		userInfo.put("token",userToken);
		RedisService.getInstance().setValue(userToken, userInfo.toJSONString() ,token_alive  );
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("id", userInfo.getInteger("id"));
		params.put("token",	userToken);
		params.put("token_createTime",new Date());
		UserService.getInstance().updateUserInfo(params);
		return userToken;
	}

	/**
	 * 检查token是否有效(免登陆)
	 * @param account
	 * @param token
	 * @return
	 */
	@POST  
	@Path("/{account}/check")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status checkUserToken(@PathParam("account") String account,
			@FormParam("userToken") String token)
	{
		Status status = new Status();
		if( !ApiUtils.checkToken(token, account) ){
			status.setOk(false);
			status.setMessage("invalid token");
			return status;
		}else{
			RedisService.getInstance().expire(token,token_alive);
			status.setOk(true);
		}
		return status;
	}
	
	/**
	 * 检查用户是否存在
	 * @param account
	 * @param accountType
	 * @return
	 */
	@POST  
	@Path("/checkUser")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public String checkUser(@FormParam("userToken") String account,
			@FormParam("type") String accountType) {
		JSONObject userInfo = UserService.getInstance().checkUser(accountType, account);
		JSONObject info = new JSONObject();
		if(userInfo != null) {
			info.put("ok", true);
			info.put("result", userInfo);
		} else {
			info.put("ok", false);
			info.put("message", "账户不存在");
		}
		return info.toJSONString();
	}
	
	/**
	 * 创建账号
	 * @param account
	 * @param passwd
	 * @param accountType
	 * @param autologin
	 * @param accessToken
	 * @param expireTime
	 * @return
	 */
	@POST  
	@Path("/createUser")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public String createAccout(@FormParam("userToken") String account, 
			@FormParam("passwd") String passwd,
			@FormParam("type") String accountType,
			@FormParam("authCode") String authCode,
			@DefaultValue("false") @FormParam("autoLogin") String autologin,
			@DefaultValue("") @FormParam("accessToken") String accessToken,
			@DefaultValue("-1") @FormParam("expire") String expireTime)
	{
		GeneralJSONResult status = new GeneralJSONResult();
		status.setOk( false );
		if( UserService.getInstance().accountExist(account,accountType) ){
			status.setMessage("账号已存在");
		}else{
			if( StringUtils.isBlank(accountType)){
				status.setOk(false);
				status.setMessage("注册账号类型不能位空");
				return status.toString();
			}
			int len = account.length();
			if( len > 60 ){
				status.setMessage("账号名过长,账号长度在6-60之间");
				return status.toString();
			}else if( len < 6 ){
				status.setMessage("账号名过短,账号长度在6-50之间");
				return status.toString();
			}
			if( accountType.compareTo("PHONE") == 0 ){
				String code = PublicApi.authCache.getIfPresent(account);
				if( code == null ){
					status.setMessage("验证码已过期");
					return status.toString();
				}
				if( code.compareTo(authCode) != 0 ){
					status.setMessage("无效的验证码");
					return status.toString(); 
				}
			}
			
			JSONObject info = new JSONObject();
			boolean ret = UserService.getInstance().createAccount(account, passwd,
					accountType,accessToken,expireTime,info);
			if( ret ){
				if( !StringUtils.isBlank(autologin) && "true".compareToIgnoreCase(autologin) == 0 ){
					// 创建账号成功，并进行登录操作
					JSONObject userinfo = UserService.getInstance().getUserInfo( Integer.valueOf(info.getIntValue("id")) );
					generateUserToken(userinfo);
					userinfo.put("ok",true);
					String ak = Configurator.getInstance().getString("qiniu_accesstoken");
					String sk =  Configurator.getInstance().getString("qiniu_secretkey");
					String uploadToken = "";
					if( StringUtils.isNotEmpty(ak) && StringUtils.isNotEmpty(sk)){
						Auth auth = Auth.create(ak, sk);
						String bucket = Configurator.getInstance().getString("qiniu_bucket");
						uploadToken = auth.uploadToken(bucket);
					}
					userinfo.put("uploadToken", uploadToken);
					return userinfo.toJSONString();
				}
				info.put("ok",true);
				return info.toJSONString();
			}else{
				status.setOk( false );
				status.setMessage("创建账号失败，请联系管理员");
			}
		}
		return status.toString();
	}

	@DELETE
	@Path("/{account}/delete")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status deleteAccount(  @PathParam("account") String account ,
			@FormParam("token") String token,
			@DefaultValue("") @FormParam("targetid") String target)
	{
		Status s = new Status();
		JSONObject obj = ApiUtils.checkAndGetUserInfo(token,account);
		if( obj == null ){
			s.setOk(false);
			s.setMessage("invalid token");
			return s;
		}
		int role = obj.getInteger("role");
		if( role != 1 ){
			if( !StringUtils.isEmpty(target) ){
				s.setOk(false);
				s.setMessage("没有权限删除他人账号");
				return s;
			}
			//只能删除自己账号
			boolean ret = UserService.getInstance().deleteAccount(obj.getIntValue("id"));
			if( ret ){
				s.setOk(true);
				RedisService.getInstance().delete(token);
			}else{
				s.setOk(false);
				s.setMessage("删除用户账号失败");
			}
		}else{
			if( StringUtils.isEmpty(target) ){
				s.setOk(false);
				s.setMessage("管理员无法删除自身账号");
				return s;
			}
			//管理员可以删除任意指定的账号
			boolean ret = UserService.getInstance().deleteAccount(Integer.parseInt(target));
			if( ret ){
				s.setOk(true);
			}else{
				s.setOk(false);
				s.setMessage("删除用户账号失败");
			}
		}
		return s;
	}
	
	/**
	 * 设置用户头像
	 * @param token
	 * @param data 头像图片，base64编码
	 * @return
	 */
	@POST  
	@Path("/{account}/updateAvatar")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ImageInfo setUserAvator( @PathParam("account") String account,
			@FormParam("filename") String fileName,
			@FormParam("data") String imgData,
			@FormParam("token") String token)
	{
		ImageInfo img = new ImageInfo();
		if( !ApiUtils.checkToken(token, account) ){
			img.setOk(false);
			img.setMessage("invalid token");
			return img;
		}
		String imgToken = StoreService.getInstance().storeImg(account,fileName,imgData);
		if( imgToken != null ){
			if( UserService.getInstance().updateAvator(account, imgToken, null) ){
				img.setOk(true);
				img.setImgToken(imgToken);
				img.setThumbImgToken(null);
			}else{
				img.setOk(false);
				img.setMessage("设置用户头像数据操作失败");
			}
		}else{
			img.setOk(false);
			img.setMessage("保存图片数据失败");
		}
		return img;
	}


	/**
	 * 更改密码
	 * @param token
	 * @param oldpwd
	 * @param newpwd
	 * @return
	 */
	@POST  
	@Path("/{account}/changePWD")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status changePWD( 
			@PathParam("account") String account,
			@FormParam("token")  String token,
			@FormParam("oldpwd") String oldpwd,
			@FormParam("newpwd") String newpwd)
	{
		Status status = new Status();
		if( !ApiUtils.checkToken(token, account) ){
			status.setOk(false);
			status.setMessage("invalid token");
			return status;
		}
		RetCode ret = UserService.getInstance().updatePasswd(account, oldpwd,newpwd );
		if( ret == RetCode.OK ){
			status.setOk(true);
		}else{
			status.setOk( false );
			status.setMessage( ret.getDesc() );
		}
		return status;
	}

	/**
	 * 更改用户昵称
	 * @param token
	 * @param nickName
	 * @return
	 */
	@POST  
	@Path("/{account}/changeNickName")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status updateNickName( 	
			@PathParam("account") 	String account,
			@FormParam("token")  	String token,
			@FormParam("nickName") 	String nickName ){
		Status status = new Status();
		if( !ApiUtils.checkToken(token, account) ){
			status.setOk(false);
			status.setMessage("invalid token");
			return status;
		}
		boolean ret = UserService.getInstance().updateNickName(account, nickName);
		if( ret ){
			status.setOk(true);
		}else{
			status.setOk(false);
			status.setMessage("更新昵称成功");
		}
		return status;
	}
	

	/**
	 * 获取用户详情
	 * @param account
	 * @param token
	 * @param userid
	 * @return
	 */
	@POST  
	@Path("/{account}/userInfo")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public String userInfo( 	
			@PathParam("account") 	String account,
			@FormParam("token")  	String token,
			@FormParam("userid") String userid ) {
		GeneralJSONResult status = new GeneralJSONResult();
		if( StringUtils.isEmpty(userid) ){
			status.setOk(false);
			status.setMessage("userid is empty");
			return status.toString();
		}
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(token, account);
		if( accountInfo == null ){
			status.setOk(false);
			status.setMessage("invalid token");
			return status.toString();
		}
		JSONObject result = UserService.getInstance().getUserInfo( Integer.parseInt(userid) );
		if( result!=null ){
			status.setOk(true);
			status.setData( result );
		}else{
			status.setOk(false);
			status.setMessage("获取用户信息失败");
		}
		return status.toString();
	}
	
	@POST
	@Path("/{account}/update")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status updateUserInfo(@PathParam("account") String account, 
			@FormParam("token") String userToken ,
			@FormParam("nickname") String nickname,
			@FormParam("gender") String gender,
			@FormParam("weight") String weight,
			@FormParam("height") String height,
			@FormParam("location") String location,
			@FormParam("birthday") String birthday,
			@FormParam("coverimg") String cover,
			@FormParam("userid") String userid,
			@FormParam("label") String label,
			@FormParam("settings") String settings
			){
		Status st = new Status();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		Integer uid = accountInfo.getInteger("id");
		if( StringUtils.isNotEmpty(userid) ){
			if( !ApiUtils.isWechatUser( accountInfo ) ){
				st.setOk(false);
				st.setMessage("权限不足");
				return st;
			}
			uid = Integer.valueOf(userid);
		}
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("id", uid );
		if( !StringUtils.isBlank(nickname) )
			params.put("nickname", nickname);
		if( !StringUtils.isBlank(location) )
			params.put("location", location);
		if( !StringUtils.isBlank(weight) )
			params.put("weight", Integer.parseInt(weight));
		if( !StringUtils.isBlank(height) )
			params.put("height", Integer.parseInt(height));
		if( !StringUtils.isBlank(gender) )
			params.put("sex", Integer.parseInt(gender));
		if( !StringUtils.isBlank(birthday) ){
			long date = Long.parseLong(birthday);
			Date birthdayDate = new Date(date);
			params.put("birthday", birthdayDate);
		}
		if( !StringUtils.isBlank(cover) )
			params.put("coverimg", cover);
		if( !StringUtils.isBlank(label) )
			params.put("label", label);
		if( !StringUtils.isBlank(settings)&& settings.length()>0)
			params.put("settings", settings);
		params.put("account", account);
		for(String k:params.keySet()){
			System.out.println("update user="+account+" with key="+k+" value="+params.get(k));
		}
		RetCode ret = UserService.getInstance().updateUserInfo(params);
		if( ret == RetCode.OK ){
			st.setOk(true);
			JSONObject userinfo = UserService.getInstance().getUserInfo( uid );
			if( userinfo!=null ){
				RedisService.getInstance().setValue(userToken, userinfo.toJSONString() ,token_alive  );
			}
		}
		else{
			st.setOk( false );
			st.setMessage( ret.getDesc() );
		}
		return st;
	}
	
	
	/**
	 * 设定用户位置信息
	 * @param account
	 * @param userToken
	 * @param loc
	 * @return
	 */
	@POST
	@Path("/{account}/location")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status updateUserLocation(@PathParam("account") String account, 
			@FormParam("token") String userToken ,
			@FormParam("longitude") String longitude,
			@FormParam("latitude") String latitude){
		Status st = new Status();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		
		String key = account+"_location";
		String val = RedisService.getInstance().getValue(key);
		String location = latitude+","+longitude;
		RetCode ret = RetCode.OK;
		if( val == null ){
			ret = UserService.getInstance().updateUserPosition(accountInfo, latitude, longitude);
			RedisService.getInstance().setValue(key, location+"#"+System.currentTimeMillis());
		}else{
			String vals[] = val.split("#");
			long tm = Long.parseLong(vals[1]);
			if( System.currentTimeMillis() - tm > 60000 ){
				if( vals[0].compareTo(location) != 0){
					ret = UserService.getInstance().updateUserPosition(accountInfo, latitude, longitude );
					RedisService.getInstance().setValue(key, location+"#"+System.currentTimeMillis());
				}
			}
		}
		
		if( ret == RetCode.OK )
			st.setOk(true);
		else{
			st.setOk( false );
			st.setMessage( ret.getDesc() );
		}
		return st;
	}
	
	/**
	 * 获取用户位置信息
	 * @param account
	 * @param userToken
	 * @return
	 */
	@POST
	@Path("/{account}/position")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Position getUserLocation(@PathParam("account") String account, 
			@FormParam("token") String userToken ){
		Position st = new Position();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		Integer locid = accountInfo.getInteger("locationid");
		if( locid == null || locid == 0 ){
			st.setOk(true);
			st.setMessage("no position info");
		}else{
			JSONObject obj = CloudMapService.getInstance().getUserLocation(locid);
			if( obj == null ){
				st.setOk(false);
				st.setMessage("获取用户位置信息失败");
			}else{
				int status = obj.getIntValue("status");
				if( status != 1 ){
					st.setOk(false);
					st.setMessage(obj.getString("info"));
				}else{
					st.setOk(true);
					Object o = obj.get("datas");
					if( o instanceof JSONArray ){
						JSONArray a = (JSONArray)o;
						JSONObject pos = (JSONObject)a.get(0);
						String p = pos.getString("_location");
						String ps[] = p.split(",");
						String name = accountInfo.getString("nickName");
						if( StringUtils.isBlank(name) ){
							name = accountInfo.getString("account");
						}
						st.setLocID( Integer.parseInt(pos.getString("_id")) );
						st.setLongitude(ps[0]);
						st.setLatitude(ps[1]);
						st.setName(name);
						st.setCreateTime(pos.getString("_createtime"));
						st.setUpdateTime( pos.getString("_updatetime"));
						st.setUserid(Integer.parseInt(pos.getString("userid")));
						st.setType(pos.getIntValue("type"));
					}
					else
					{
						st.setOk(false);
						st.setMessage("未知的响应数据格式");
					}
				}
			}
		}

		return st;
	}
	
	
	/**
	 * 跟踪指定用户位置信息
	 * @param account
	 * @param userToken
	 * @return
	 */
	@POST
	@Path("/{account}/track")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Position trackUserLocation(@PathParam("account") String account, 
			@FormParam("token") String userToken,
			@FormParam("locationid") String locid ){
		Position st = new Position();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		if( locid == null || !StringUtils.isNumeric(locid) ){
			st.setOk( true );
			st.setMessage("no position info");
		}else{
			JSONObject obj = CloudMapService.getInstance().getUserLocation( Integer.parseInt(locid) );
			if( obj == null ){
				st.setOk(false);
				st.setMessage("获取用户位置信息失败");
			}else{
				int status = obj.getIntValue("status");
				if( status != 1 ){
					st.setOk(false);
					st.setMessage(obj.getString("info"));
				}else{
					st.setOk(true);
					Object o = obj.get("datas");
					if( o instanceof JSONArray ){
						JSONArray a = (JSONArray)o;
						JSONObject pos = (JSONObject)a.get(0);
						String p = pos.getString("_location");
						String ps[] = p.split(",");
						String name = accountInfo.getString("nickName");
						if( StringUtils.isBlank(name) ){
							name = accountInfo.getString("account");
						}
						st.setLocID( Integer.parseInt(pos.getString("_id")) );
						st.setLongitude(ps[0]);
						st.setLatitude(ps[1]);
						st.setName(name);
						st.setCreateTime(pos.getString("_createtime"));
						st.setUpdateTime( pos.getString("_updatetime"));
						st.setUserid(Integer.parseInt(pos.getString("userid")));
						st.setType(pos.getIntValue("type"));
					}
					else
					{
						st.setOk(false);
						st.setMessage("未知的响应数据格式");
					}
				}
			}
		}

		return st;
	}
	
	/**
	 * 获取附近用户信息
	 * @param account
	 * @param userToken
	 * @return
	 */
	@POST
	@Path("/{account}/localUsers")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public String getLocalUsers(@PathParam("account") String account, 
			@FormParam("token") String userToken,
			@FormParam("city") String city,
			@DefaultValue("0") @FormParam("type") String userType){
		GeneralJSONResult st = new GeneralJSONResult();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st.toString();
		}
		if( city == null || StringUtils.isBlank(city) ){
			st.setOk( false );
			st.setMessage("city is empty");
		}else{
			Integer userid = accountInfo.getInteger("id");
			JSONArray obj = UserService.getInstance().getLocalUsers(userid,city, Integer.parseInt(userType));
			if( obj == null ){
				st.setOk(false);
				st.setMessage("获取用户位置信息失败");
			}else{
				st.setOk(true);
				st.setData(obj);
			}
		}
		return st.toString();
	}
	
	
	/**
	 * 绑定用户资料
	 * @param account
	 * @param userToken
	 * @param loc
	 * @return
	 */
	@POST
	@Path("/{account}/data")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status bindUserData(@PathParam("account") String account, 
			@FormParam("token") String userToken ,
			@FormParam("type") String type,
			@FormParam("value") String value,
			@FormParam("bindtoken") String token,
			@FormParam("expireTime") String expireTime){
		Status st = new Status();
		if( StringUtils.isBlank(type) ){
			st.setOk(false);
			st.setMessage("参数错误，缺少必要的参数");
			return st;
		}
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		Integer userid = accountInfo.getInteger("id");
		UserData ud = new UserData();
		ud.setUserID( userid );
		ud.setBindType( type );
		ud.setValue(value);
		ud.setToken(token);
		int expire = -1;
		if( !StringUtils.isBlank(expireTime) && StringUtils.isNumeric(expireTime)){
			expire = Integer.parseInt(expireTime);
		}
		ud.setExpireTime(expire);
		RetCode ret = UserService.getInstance().bindUserData(ud);
		if( ret == RetCode.OK )
			st.setOk(true);
		else{
			st.setOk( false );
			st.setMessage( ret.getDesc() );
		}
		return st;
	}
	
	/**
	 * 获取用户列表信息
	 * @param account
	 * @param userToken
	 * @param from        供分页使用，提取的起始记录位置
	 * @param limit       显示的记录条数
	 * @return
	 */
	@POST
	@Path("/{account}/userList")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ContactList getUserList(@PathParam("account") String account, 
			@FormParam("token") String userToken ,
			@FormParam("fromIndex") String from,
			@FormParam("limit") String limit){
		
		ContactList contacts = new ContactList();
		if( !ApiUtils.isAdmin(userToken, account) ){
			contacts.setOk(false);
			contacts.setMessage("无效的token或不是管理员");
			return contacts;
		}
		Integer fromIndex = StringUtils.isBlank(from)?null:Integer.parseInt(from);
		Integer limitSize = StringUtils.isBlank(limit)?null:Integer.parseInt(limit);
		if( limitSize!= null && limitSize <= 0 ){
			limitSize = 999;
		}
		int count = UserService.getInstance().getUserCount(account);
		List<ContactItem> result = UserService.getInstance().getUserList(account, fromIndex, limitSize);
		contacts.setOk(true);
		contacts.setTotal( count );
		contacts.setResult( result );
		contacts.setFrom( fromIndex == null? 0 : fromIndex );
		return contacts;
	}
	
	/**
	 * 设定用户角色id
	 * @param account
	 * @param userToken
	 * @param id
	 * @param role
	 * @return
	 */
	@POST
	@Path("/{account}/updateRole")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status updateUserRole(@PathParam("account") String account, 
			@FormParam("token") String userToken ,
			@FormParam("userid") String id,
			@FormParam("role") String role ){
		Status status = new Status();
		if( !ApiUtils.isAdmin(userToken, account) ){
			status.setOk(false);
			status.setMessage("无效的token或不是管理员");
			return status;
		}
		if( StringUtils.isEmpty(role) || StringUtils.isEmpty(id) ){
			status.setOk(false);
			status.setMessage("参数异常");
			return status;
		}
		if( !StringUtils.isNumeric(role) || !StringUtils.isNumeric(id) ){
			status.setOk(false);
			status.setMessage("参数格式错误");
			return status;
		}
		boolean ret = UserService.getInstance().updateUserRole(id,Integer.parseInt(role));
		if( ret ){
			status.setOk(true);
			JSONObject userinfo = UserService.getInstance().getUserInfo( Integer.valueOf(id) );
			if( userinfo!=null ){
				RedisService.getInstance().setValue(userToken, userinfo.toJSONString() ,token_alive  );
			}
		}else{
			status.setOk(false);
			status.setMessage("服务器内部异常");
		}
		return status;
	}

	/**
	 * 获取联系人列表
	 * 包括一般联系人，群，标签等
	 * @param account
	 * @param userToken
	 * @param from
	 * @param limit
	 * @return
	 */
	@POST
	@Path("/{account}/contacts")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ContactList getContactList(@PathParam("account") String account, 
			@FormParam("token") String userToken,
			@DefaultValue("-1") @FormParam("type") String type,
			@FormParam("fromIndex") String from,
			@FormParam("limit") String limit){
		
		ContactList contacts = new ContactList();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			contacts.setOk(false);
			contacts.setMessage("invalid token");
			return contacts;
		}
		Integer r = 0;
		if( type.compareTo("-1") == 0 )
		{
			r = accountInfo.getInteger("role")>1?0:accountInfo.getInteger("role");
		}else{
			r = Integer.parseInt(type);
		}
		List<ContactItem> result = UserService.getInstance().getContacts(
				accountInfo.getInteger("id"),
				r,
				StringUtils.isBlank(from)?null:Integer.valueOf(from),
				StringUtils.isBlank(limit)?null:Integer.valueOf(limit) );
		if( result != null ){
			contacts.setOk(true);
			if( from != null && limit != null ){
				contacts.setTotal( UserService.getInstance().getContactCount(accountInfo.getInteger("id"),r) );
			}else{
				contacts.setTotal( result.size() );
			}
			
			contacts.setResult( result );
			contacts.setFrom( 0 );
		}else{
			contacts.setOk(false);
			contacts.setMessage("服务器内部异常");
		}
		return contacts;
	}
	
	/**
	 * 获取跑团列表
	 * @param account
	 * @param token
	 * @param owner
	 * @param from
	 * @param limit
	 */
	@POST
	@Path("/{account}/getRunGroup")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ContactList getRunGroup(@PathParam("account") String account, 
			@FormParam("token") String userToken,
			@FormParam("owner") Integer owner,
			@FormParam("fromIndex") String from,
			@FormParam("limit") String limit) {
		ContactList contacts = new ContactList();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			contacts.setOk(false);
			contacts.setMessage("invalid token");
			return contacts;
		}
		
		List<ContactItem> result = UserService.getInstance().getRunGroup(accountInfo.getInteger("id"),
				owner,
				StringUtils.isBlank(from)?null:Integer.valueOf(from),
				StringUtils.isBlank(limit)?null:Integer.valueOf(limit) );
		
		if( result != null ){
			contacts.setOk(true);
			if( from != null && limit != null ){
				contacts.setTotal( UserService.getInstance().getRunGroupCount(accountInfo.getInteger("id"), owner) );
			}else{
				contacts.setTotal( result.size() );
			}
			
			contacts.setResult( result );
			contacts.setFrom( 0 );
		}else{
			contacts.setOk(false);
			contacts.setMessage("服务器内部异常");
		}
		return contacts;
	}
	
	/**
	 * 更新联系人列表
	 * 包括一般联系人，群，标签等
	 * @param account
	 * @param userToken
	 * @param cv
	 * @param from
	 * @param limit
	 * @return
	 */
	@POST
	@Path("/{account}/syncContacts")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ContactList syncContactList(@PathParam("account") String account, 
			@FormParam("token") String userToken,
			@DefaultValue("-1") @FormParam("type") String type,
			@FormParam("cv") String cv,
			@FormParam("fromIndex") String from,
			@FormParam("limit") String limit){
		
		ContactList contacts = new ContactList();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			contacts.setOk(false);
			contacts.setMessage("invalid token");
			return contacts;
		}
		Integer r = 0;
		if( type.compareTo("-1") == 0 )
		{
			r = accountInfo.getInteger("role")>1?0:accountInfo.getInteger("role");
		}else{
			r = Integer.parseInt(type);
		}
		Integer cvInteger = StringUtils.isBlank(cv)?0:Integer.valueOf(cv);
		List<ContactItem> result = UserService.getInstance().syncContacts(accountInfo.getInteger("id"),
		r,
		cvInteger,
		StringUtils.isBlank(from)?null:Integer.valueOf(from),
		StringUtils.isBlank(limit)?null:Integer.valueOf(limit) );
		if( result != null ){
			contacts.setOk(true);
			if( from != null && limit != null ){
				contacts.setTotal( UserService.getInstance().syncContactCount(accountInfo.getInteger("id"),
						r,
						cvInteger));
			}else{
				contacts.setTotal( result.size() );
			}
			
			contacts.setResult( result );
			contacts.setFrom( 0 );
		}else{
			contacts.setOk(false);
			contacts.setMessage("服务器内部异常");
		}
		return contacts;
	}
	
	/**
	 * 申请添加联系人
	 * @param account
	 * @param userToken
	 * @param contactid
	 * @return
	 */
	@POST
	@Path("/{account}/addContact")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ApplicationStatus addContact(@PathParam("account") String account, 
			@FormParam("token") String userToken,
			@FormParam("contactid") String contactid,
			@FormParam("type") String contacttype,
			@FormParam("message") String message,
			@FormParam("userid") String userid
			){
		ApplicationStatus as = new ApplicationStatus();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			as.setOk(false);
			as.setMessage("invalid token");
			return as;
		}
		if( StringUtils.isBlank(contactid) || StringUtils.isBlank(contacttype) ){
			as.setOk(false);
			as.setMessage("无效的参数");
			return as;
		}
		String account_name = accountInfo.getString("account");
		Integer uid = accountInfo.getInteger("id");
		if( StringUtils.isNotEmpty(userid) ){
			if( !ApiUtils.isWechatUser( accountInfo ) ){
				as.setOk(false);
				as.setMessage("权限不足");
				return as;
			}
			if( Integer.valueOf(contacttype)<=0 ){
				as.setOk(false);
				as.setMessage("指定userid时只能主动加入群组类型");
				return as;
			}
			uid = Integer.valueOf(userid);
			account_name = UserService.getInstance().getUserAccountName( uid );
			if( StringUtils.isBlank( account_name ) ){
				as.setOk(false);
				as.setMessage("userid无效");
				return as;
			}
		}

		RetCode ret = UserService.getInstance().addContact(uid,account_name, 
				Integer.valueOf(contactid), Integer.valueOf(contacttype),message );
		if( ret == RetCode.CONTACT_ADDOK || ret == RetCode.CONTACT_WAITFORAUTH ){
			as.setOk( true );
		}else{
			as.setOk( false );
			as.setMessage( ret.getDesc());
		}
		as.setStatusCode( ret.getCode() );
		return as;
	}
	
	/**
	 * 添加用户通讯录联系人
	 * @param account
	 * @param userToken
	 * @param contactid
	 * @return
	 */
	@POST
	@Path("/{account}/addContacts")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public GeneralJSONResult addContacts(@PathParam("account") String account, 
			@FormParam("token") String userToken,
			@FormParam("data") String contactsData){
		GeneralJSONResult as = new GeneralJSONResult();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			as.setOk(false);
			as.setMessage("invalid token");
			return as;
		}
		if( StringUtils.isBlank(contactsData)){
			as.setOk(false);
			as.setMessage("无效的参数");
			return as;
		}
		Integer uid = accountInfo.getInteger("id");
		try{
			JSONArray data = JSONArray.parseArray(contactsData);
			RetCode ret = UserService.getInstance().addUserContacts(uid, data);
			if( ret == RetCode.OK){
				JSONArray contacts = UserService.getInstance().getUserContactsFriends(uid);
				JSONArray newContacts = new JSONArray();
				if( contacts != null ){
					for(int i=0;i<contacts.size();++i){
						JSONObject contact = contacts.getJSONObject(i);
						int nUpdate = data.size();
						for(int j=0;j<nUpdate;++j){
							JSONObject c = data.getJSONObject(j);
							String ocid = c.getString("cid");
							String cid = contact.getString("cid");
							if( ocid.compareTo(cid) == 0){
								newContacts.add(contact);
								break;
							}
						}
					}
				}
				as.setData(newContacts);
				as.setOk( true );
			}else{
				as.setOk( false );
				as.setMessage( ret.getDesc());
			}
		}catch(Exception e){
			as.setOk( false );
			as.setMessage( "参数格式错误" );
		}
		return as;
	}
	
	/**
	 * 删除通讯录联系人
	 * @param account
	 * @param userToken
	 * @param contactid
	 * @return
	 */
	@POST
	@Path("/{account}/deleteContacts")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status deleteContacts(@PathParam("account") String account, 
			@FormParam("token") String userToken,
			@FormParam("data") String contactsData){
		Status as = new Status();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			as.setOk(false);
			as.setMessage("invalid token");
			return as;
		}
		if( StringUtils.isBlank(contactsData)){
			as.setOk(false);
			as.setMessage("无效的参数");
			return as;
		}
		Integer uid = accountInfo.getInteger("id");
		try{
			JSONArray data = JSONArray.parseArray(contactsData);
			RetCode ret = UserService.getInstance().deleteUserContacts(uid, data);
			if( ret == RetCode.OK){
				as.setOk( true );
			}else{
				as.setOk( false );
				as.setMessage( ret.getDesc());
			}
		}catch(Exception e){
			as.setOk( false );
			as.setMessage( "参数格式错误" );
		}
		return as;
	}
	
	/**
	 * 获取通讯好友
	 * @param account
	 * @param userToken
	 * @return
	 */
	@POST
	@Path("/{account}/getUserContactsFriends")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public GeneralJSONResult getContactsFriends(@PathParam("account") String account, 
			@FormParam("token") String userToken){
		GeneralJSONResult as = new GeneralJSONResult();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			as.setOk(false);
			as.setMessage("invalid token");
			return as;
		}
		
		Integer uid = accountInfo.getInteger("id");
		try{
			JSONArray data = UserService.getInstance().getUserContactsFriends(uid);
			if( data !=null){
				as.setOk( true );
				as.setData( data );
			}else{
				as.setOk( false );
				as.setMessage( "查询数据异常") ;
			}
		}catch(Exception e){
			as.setOk( false );
			as.setMessage( "参数格式错误" );
		}
		return as;
	}
	
	/**
	 * 删除好友
	 * @param account
	 * @param userToken
	 * @param contactid
	 * @return
	 */
	@DELETE
	@Path("/{account}/delContact")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status deleteContact(@PathParam("account") String account, 
			@FormParam("token") String userToken,
			@FormParam("contactid") String contactid,
			@FormParam("type") String type){
		Status as = new Status();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			as.setOk(false);
			as.setMessage("invalid token");
			return as;
		}
		if( StringUtils.isBlank(contactid) ){
			as.setOk(false);
			as.setMessage("无效的参数");
			return as;
		}
		Integer userid = accountInfo.getInteger("id");
		RetCode ret = UserService.getInstance().delContact(userid, accountInfo.getString("account"), 
				Integer.valueOf(contactid),
				Integer.valueOf(type));
		if( ret == RetCode.OK ){
			as.setOk( true );
		}else{
			as.setOk( false );
			as.setMessage(ret.getDesc());
		}
		return as;
	}
	
	/**
	 * 显示用户收到的好友添加申请
	 * @param account
	 * @param userToken
	 * @return
	 */
	@POST
	@Path("/{account}/applications")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ApplicationList getApplications(@PathParam("account") String account, 
			@FormParam("token") String userToken,
			@FormParam("appTime") String appTime){
		ApplicationList as = new ApplicationList();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			as.setOk(false);
			as.setMessage("invalid token");
			return as;
		}
		Integer userid = accountInfo.getInteger("id");
		List<ApplicationInfo> result = UserService.getInstance().getApplications(userid,appTime);
		if( result != null ){
			as.setOk( true );
			as.setResult( result );
		}else{
			as.setOk( false );
			as.setMessage("服务器内部异常");
		}
		return as;
	}
	
	/**
	 * 处理收到的添加请求
	 * @param account
	 * @param appid
	 * @param userToken
	 * @param type
	 * @param contactid
	 * @param enable 处理结果"enable"允许添加 "disable"或其它值则表示拒绝
	 * @return
	 */
	@POST
	@Path("/{account}/application")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status processApplication(@PathParam("account") String account, 
			@FormParam("appid") String appid,
			@FormParam("token") String userToken,
			@FormParam("apptype") String type,
			@FormParam("targetid") String contactid,
			@FormParam("result") String result){
		Status st = new Status();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		if(  StringUtils.isBlank(appid) || StringUtils.isBlank(contactid) || StringUtils.isBlank(contactid)||StringUtils.isBlank(result) ){
			st.setOk(false);
			st.setMessage("无效的参数");
			return st;
		}
		Integer userid = accountInfo.getInteger("id");
		String userAccount = accountInfo.getString("account");
		boolean ret = UserService.getInstance().processApplication(userid, userAccount, Integer.valueOf(contactid), 
				Integer.valueOf(appid), Integer.valueOf(type), result);
		if( ret ){
			st.setOk(true);
		}else{
			st.setOk(false);
			st.setMessage("处理申请请求失败");
		}
		return st;
	}
	
	/**
	 * 搜索用户
	 * @param account
	 * @param userToken
	 * @param term
	 * @return
	 */
	@POST
	@Path("/{account}/users")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ContactList searchUser(@PathParam("account") String account, 
			@FormParam("token") String userToken,
			@FormParam("term") String term){
		ContactList st = new ContactList();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		if(  StringUtils.isBlank(term) ){
			st.setOk(false);
			st.setMessage("搜索条件不能为空");
			return st;
		}
		Integer userid = accountInfo.getInteger("id");
		List<ContactItem> res = UserService.getInstance().searchUser(term, userid);
		if( res!=null ){
			st.setFrom(0);
			st.setTotal( res.size() );
			st.setResult( res );
			st.setOk(true);
		}else{
			st.setOk(false);
			st.setMessage("处理请求失败");
		}
		return st;
	}
	
	/**
	 * 创建群组
	 * @param account
	 * @param userToken
	 * @param data
	 * @return
	 */
	@POST
	@Path("/{account}/group")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status createGroup(@PathParam("account") String account, 
			@FormParam("token") String userToken,
			@FormParam("group") String data){
		Status st = new Status();
		JSONObject accountInfo =ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		if(  StringUtils.isBlank(data) ){
			st.setOk(false);
			st.setMessage("创建组的描述不能为空");
			return st;
		}
		JSONObject group = JSONObject.parseObject(data);
		String gpName = group.getString("groupname");
		String gpDesc = group.getString("groupdesc");
		Boolean isPublic = group.getBoolean("public");
		Boolean approval = group.getBoolean("approval");
		Integer maxUsers = group.getInteger("maxusers");
		Integer type = group.getInteger("type");
		String address = group.getString("coordname");
		String coord = group.getString("coord");
		String avatarImg = group.getString("avatarImg");
		String coverImages = group.getString("coverImgs");
		if( type == null || type <= 0 ){
			st.setOk( false );
			st.setMessage("缺少分组类型，或分组类型无效");
			return st;
		}
		if( isPublic == null || approval == null || coord == null || address == null)
		{
			st.setOk( false );
			st.setMessage("缺少必要的参数");
			return st;
		}
		if( maxUsers == null ){
			maxUsers = 200;
		}
		if(gpDesc == null ){
			gpDesc = "";
		}
	
		Object members = group.get("memebers");
		List<Member> memberList = new ArrayList<Member>();
		if( members != null && members instanceof JSONArray ){
			JSONArray arrays = (JSONArray)members;
			for(Object each : arrays ){
				if( each instanceof JSONObject ){
					JSONObject m = (JSONObject)each;
					if( StringUtils.isEmpty( m.getString("account") ) )
						continue;
					Member mb = new Member();
					mb.setAccount( m.getString("account") );
					mb.setId(m.getInteger("id"));
					memberList.add( mb );
				}
			}
		}
		if( StringUtils.isEmpty(gpName) ){
			StringBuilder sb = new StringBuilder();
			sb.append( accountInfo.getString("name") );
			if( memberList.size() > 0 ){
				for( Member m:memberList ){
					sb.append(",");
					sb.append( m.getAccount() );
				}
			}
			if( sb.length() < 100 )
				gpName = sb.toString();
			else
				gpName = sb.substring(0,100);
		}
		Integer userid = accountInfo.getInteger("id");
		Integer vid = UserService.getInstance().createGroup(userid, account, gpName,gpDesc
				, isPublic, maxUsers, approval,type, memberList,address,coord,avatarImg,coverImages);
		if( vid == null ){
			st.setOk( false );
			st.setMessage("服务器内部错误,创建群组失败");
		}else{
			st.setOk(true);
			st.setMessage(String.valueOf(vid));
		}
		return st;
	}

	/**
	 * 删除群组
	 * @param account
	 * @param userToken
	 * @param groupid
	 * @return
	 */
	@DELETE
	@Path("/{account}/group")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status deleteGroup(@PathParam("account") String account,
			@FormParam("token") String userToken,
			@FormParam("groupid") String groupid ){
		Status st = new Status();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		if(  StringUtils.isBlank(groupid) ){
			st.setOk(false);
			st.setMessage("分组id不能为空");
			return st;
		}
		Integer userid = accountInfo.getInteger("id");
		RetCode ret = UserService.getInstance().deleteGroup(userid, Integer.parseInt(groupid));
		if( ret == RetCode.OK ){
			st.setOk( true );
		}else{
			st.setOk( false );
			st.setMessage(ret.getDesc());
		}
		return st;
	}
	
	/**
	 * 查看群主成员
	 * @param account
	 * @param userToken
	 * @param groupid
	 * @param from
	 * @param limit
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@POST
	@Path("/{account}/group/members")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ContactList showGroupMembers(@PathParam("account") String account,
			@FormParam("token") String userToken,
			@FormParam("groupid") String groupid,
			@FormParam("fromIndex") String from,
			@FormParam("limit") String limit){
		ContactList st = new ContactList();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		if(  StringUtils.isBlank(groupid) ){
			st.setOk(false);
			st.setMessage("分组id不能为空");
			return st;
		}
		if(  !StringUtils.isNumeric(groupid) ){
			st.setOk(false);
			st.setMessage("分组id必须为数字");
			return st;
		}
		Integer fromIndex = StringUtils.isBlank(from)?null:Integer.parseInt(from);
		Integer limitSize = StringUtils.isBlank(limit)?null:Integer.parseInt(limit);
		if( limitSize!=null && limitSize <= 0 ){
			limitSize = 999;
		}
		Integer userid = accountInfo.getInteger("id");
		Map<String,Object> result = new HashMap<String,Object>();
		RetCode r = UserService.getInstance().getGroupMembers(userid, Integer.valueOf(groupid), result, fromIndex, limitSize);
		if( r == RetCode.OK ){
			st.setOk(true);
			st.setTotal((Integer)result.get("total"));
			st.setResult((List<ContactItem>)result.get("data"));
			if( fromIndex != null )
				st.setFrom(fromIndex);
		}else{
			st.setOk(false);
			st.setMessage(r.getDesc());
		}
		return st;
	}
	
	
	/**
	 * 邀请要用加入群
	 * 
	 * @param account
	 * @param userToken
	 * @param groupid
	 * @param contactid
	 * @return
	 */
	@POST
	@Path("/{account}/group/invite")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status inviteUserJoinGroup(@PathParam("account") String account,
			@FormParam("token") String userToken,
			@FormParam("groupid") String groupid,
			@FormParam("contactid") String contactid){
		//TODO: 目前没有去验证发起添加操作的用户是否是群组的已有成员
		Status st = new Status();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		if(  StringUtils.isBlank(groupid) ){
			st.setOk(false);
			st.setMessage("分组id不能为空");
			return st;
		}
		if(  StringUtils.isBlank(contactid) ){
			st.setOk(false);
			st.setMessage("邀请的联系人id不能为空");
			return st;
		}
		Integer userid = accountInfo.getInteger("id");
		String[] contacts = contactid.split(",");
		boolean ok = true;
		JSONArray res = new JSONArray();
		for(String id : contacts){
			RetCode r = UserService.getInstance().invite(userid, Integer.parseInt(id), Integer.parseInt(groupid));
			if( r != RetCode.OK ){
				res.add(r.getDesc());
				ok = false;
			}else{
				res.add("ok");
			}
		}
		st.setOk( ok );
		st.setMessage( res.toJSONString() );
		return st;
	}
	
	/**
	 * 从群组中退出或把默认踢出群
	 * @param account
	 * @param userToken
	 * @param groupid
	 * @param uid
	 * @return
	 */
	@DELETE
	@Path("/{account}/group/remove")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status removeUserFromGroup(@PathParam("account") String account,
			@FormParam("token") String userToken,
			@FormParam("groupid") String groupid,
			@FormParam("userid") String uid){
		Status st = new Status();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		if(  StringUtils.isBlank(groupid) ){
			st.setOk(false);
			st.setMessage("分组id不能为空");
			return st;
		}
		if(  StringUtils.isBlank(uid) ){
			st.setOk(false);
			st.setMessage("移除的用户id不能为空");
			return st;
		}
		Integer userid = accountInfo.getInteger("id");
		RetCode ret = UserService.getInstance().removeUserFromGroup(userid, Integer.parseInt(uid),Integer.parseInt(groupid));
		if( ret == RetCode.OK ){
			st.setOk( true );
		}else{
			st.setOk( false );
			st.setMessage( ret.getDesc() );
		}
		return st;
	}
	
	/*
	@POST
	@Path("/{account}/group/location")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status updateGroupLocation(@PathParam("account") String account, 
			@FormParam("token") String userToken ,
			@FormParam("groupid") String groupid,
			@FormParam("location") String loc ){
		Status st = new Status();
		JSONObject accountInfo = checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		Integer userid = accountInfo.getInteger("id");
		RetCode ret = UserService.getInstance().updateLocation(loc, userid, Integer.parseInt(groupid) );
		if( ret == RetCode.OK )
			st.setOk(true);
		else{
			st.setOk( false );
			st.setMessage( ret.getDesc() );
		}
		return st;
	}
	*/
	
	/**
	 * 发布圈子数据
	 * @param account
	 * @param userToken
	 * @param message
	 * @param attachment
	 * @param settings
	 * @param accesslist
	 * @param accesstype
	 * @return
	 */
	@POST
	@Path("/{account}/talk/publish")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public String createTalk(@PathParam("account") String account,
			@FormParam("token") String userToken,
			@FormParam("message") String message,
			@FormParam("type") String type,
			@FormParam("attachment") String attachment,
			@DefaultValue("4") @FormParam("settings") String settings,
			@FormParam("accesslist") String accesslist,
			@DefaultValue("0") @FormParam("accesstype") String accesstype,
			@FormParam("location") String location){
		GeneralJSONResult st = new GeneralJSONResult();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st.toString();
		}
		if( StringUtils.isBlank(type) ){
			st.setOk(false);
			st.setMessage("类型不能为空");
			return st.toString();
		}
		if(  StringUtils.isBlank(attachment) && StringUtils.isBlank(message)){
			st.setOk(false);
			st.setMessage("attachment和message不能同时为空");
			return st.toString();
		}
		
		Integer userid = accountInfo.getInteger("id");
		int talkID = UserService.getInstance().publishTalk(userid, message, attachment, Integer.parseInt(settings),
				accesslist, Integer.parseInt(accesstype),type,location,accountInfo.getString("avatar") );
		if( talkID > 0 ){
			st.setOk( true );
			Talk talk = UserService.getInstance().getTalkInfo( talkID );
			talk.setAttachment(null);
			st.setData( (JSON)JSONObject.toJSON(talk) );
		}else{
			st.setOk( false );
			st.setMessage( "服务器消息处理失败" );
		}
		return st.toString();
	}
	
	@POST
	@Path("/{account}/talk/{talkid}/update")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status updateTalkPhoto( @PathParam("account") String account,
			@PathParam("talkid") String talkid,
			@FormParam("token") String userToken,
			@FormParam("index") String idx,
			@FormParam("data") String data,
			@FormParam("filename") String filename)
	{
		Status st = new Status();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		String resourceToken = StoreService.getInstance().storeData(account, data,"talk",filename);
		if( resourceToken != null ){
			RetCode r = UserService.getInstance().updateImageOfTalk(Integer.valueOf(talkid), resourceToken, Integer.valueOf(idx));
			if( r == RetCode.OK ){
				st.setOk( true );
				st.setMessage(resourceToken);
			}else{
				StoreService.getInstance().delData(account, resourceToken);
				st.setOk( false );
				st.setMessage( r.getDesc() );
			}
		}else{
			st.setOk(false);
			st.setMessage("存储数据异常,请检查数据格式是否为base64编码");
		}
		
		return st;
	}
	
	
	@POST
	@Path("/{account}/talk/sync")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status syncTalks( @PathParam("account") String account,
			@FormParam("token") String userToken,
			@FormParam("cv") String cv,
			@FormParam("direction") String direction )
	{
		UserTalks st = new UserTalks();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		Integer userid = accountInfo.getInteger("id");
		List<Talk> result = UserService.getInstance().syncFirendsTalks(userid, cv,Integer.valueOf(direction));
		if( result != null ){
			st.setData(result);
			st.setOk( true );
		}else{
			st.setOk(false);
			st.setMessage("获取数据异常");
		}
		return st;
	}
	
	
	/**
	 * 评论
	 * @param account
	 * @param talkid
	 * @param userToken
	 * @param comment
	 * @param commenttype
	 * @return
	 */
	@POST
	@Path("/{account}/talk/{talkid}/comment")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status comment(
			@PathParam("account") String account,
			@PathParam("talkid") String talkid,
			@FormParam("token") String userToken,
			@FormParam("comment") String comment,
			@FormParam("replyTo") String replyTo,
			@DefaultValue("0") @FormParam("commenttype") String commenttype
			){
		Status st = new Status();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		if( "commenttype".compareTo("0") == 0 && StringUtils.isBlank(comment) ){
			st.setOk(false);
			st.setMessage("评论信息不能为空");
			return st;
		}
		
		Integer userid = accountInfo.getInteger("id");
		String name = accountInfo.getString("name");
		if( StringUtils.isBlank(name) ){
			name = accountInfo.getString("account");
		}
		int commentid = UserService.getInstance().comment(Integer.parseInt(talkid),comment,
				userid, name, Integer.parseInt(commenttype),StringUtils.isNotBlank(replyTo)?Integer.parseInt(replyTo):null);
		if( commentid > 0 ){
			st.setOk( true );
			st.setMessage(String.valueOf(commentid));
		}else{
			st.setOk( false );
			st.setMessage( "评论失败" );
		}
		return st;
	}
	
	/**
	 * 删除发布到圈子中的数据
	 * @param account
	 * @param talkid
	 * @param userToken
	 * @return
	 */
	@DELETE
	@Path("/{account}/talk/{talkid}")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status deleteTalk(
			@PathParam("account") String account,
			@PathParam("talkid") String talkid,
			@FormParam("token") String userToken){
		Status st = new Status();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		if(  StringUtils.isBlank(talkid) ){
			st.setOk(false);
			st.setMessage("talkid不能为空");
			return st;
		}
		Integer userid = accountInfo.getInteger("id");
		RetCode r = UserService.getInstance().deleteTalk(Integer.parseInt(talkid),userid);
		if( r == RetCode.OK ){
			st.setOk( true );
		}else{
			st.setOk( false );
			st.setMessage( r.getDesc() );
		}
		return st;
	}
	
	/**
	 * 获取明细内容
	 * @param account
	 * @param talkid
	 * @param userToken
	 * @return
	 */
	@POST
	@Path("/{account}/talk/{talkid}")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public TalkDetails talkDetail(
			@PathParam("account") String account,
			@PathParam("talkid") String talkid,
			@FormParam("token") String userToken){
		TalkDetails st = new TalkDetails();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		if(  StringUtils.isBlank(talkid) ){
			st.setOk(false);
			st.setMessage("talkid不能为空");
			return st;
		}
		st.setTalkid( Integer.parseInt(talkid) );
		List<Comment> r = UserService.getInstance().getTalkDetail(st.getTalkid());
		if( r != null ){
			st.setOk( true );
			st.setComments( r );
		}else{
			st.setOk( false );
			st.setMessage( "获取明细失败" );
		}
		return st;
	}
	
	/** 
	 * 删除评论
	 * @param account
	 * @param talkid
	 * @param commentid
	 * @param userToken
	 * @return
	 */
	@DELETE
	@Path("/{account}/talk/{talkid}/{commentid}")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public Status deleteComment(
			@PathParam("account") String account,
			@PathParam("talkid") String talkid,
			@PathParam("commentid") String commentid,
			@FormParam("token") String userToken){
		Status st = new Status();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		Integer userid = accountInfo.getInteger("id");
		RetCode r = UserService.getInstance().deleteComment(Integer.parseInt(commentid),
				Integer.parseInt(talkid),userid);
		if( r == RetCode.OK ){
			st.setOk( true );
		}else{
			st.setOk( false );
			st.setMessage( r.getDesc() );
		}
		return st;
	}
	
	/**
	 * 获取我发布过的圈子信息
	 * @param account
	 * @param userToken
	 * @param from
	 * @return
	 */
	@POST
	@Path("/{account}/talk/list")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public UserTalks getMyTalks(
			@PathParam("account") String account,
			@FormParam("token") String userToken,
			@DefaultValue("0") @FormParam("from") String from ){
		UserTalks st = new UserTalks();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		Integer userid = accountInfo.getInteger("id");
		List<Talk> result = UserService.getInstance().getUserTalks(userid,userid,Integer.parseInt(from));
		if( result != null ){
			st.setData(result);
			st.setOk( true );
		}else{
			st.setOk(false);
			st.setMessage("获取数据异常");
		}
		return st;
	}
	
	/**
	 * 获取任意用户的圈子消息
	 * @param account
	 * @param userToken
	 * @param userid
	 * @param from
	 * @return
	 */
	@POST
	@Path("/{account}/usertalk")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public UserTalks getUserTalks(
			@PathParam("account") String account,
			@FormParam("token") String userToken,
			@FormParam("userid") String userid,
			@DefaultValue("0") @FormParam("from") String from ){
		UserTalks st = new UserTalks();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		Integer querier = accountInfo.getInteger("id");
		List<Talk> result = UserService.getInstance().getUserTalks(Integer.parseInt(userid),
				querier,Integer.parseInt(from));
		if( result != null ){
			st.setData(result);
			st.setOk( true );
		}else{
			st.setOk(false);
			st.setMessage("获取数据异常");
		}
		return st;
	}
	
	/**
	 * 获取任意用户个人相册中最新三张图片的缩略图
	 * @param account
	 * @param userToken
	 * @param userid
	 * @param from
	 * @return
	 */
	@POST
	@Path("/{account}/album3Photos")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public String geAlbum3Photos(
			@PathParam("account") String account,
			@FormParam("token") String userToken,
			@FormParam("userid") String userid){
		GeneralJSONResult st = new GeneralJSONResult();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st.toString();
		}
		Integer querier = accountInfo.getInteger("id");
		if( !StringUtils.isEmpty(userid) ){
			querier = Integer.parseInt( userid );
		}
		JSONArray result = UserService.getInstance().get3Photos(querier);
		if( result != null ){
			st.setData(result);
			st.setOk( true );
		}else{
			st.setOk(false);
			st.setMessage("获取数据为空");
		}
		return st.toString();
	}
	
	/**
	 * 获取联系人的圈子的消息
	 * @param account
	 * @param userToken
	 * @param from
	 * @return
	 */
	@POST
	@Path("/{account}/talk/friends")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public UserTalks getFriendsTalks(
			@PathParam("account") String account,
			@FormParam("token") String userToken,
			@DefaultValue("0") @FormParam("from") String from,
			@DefaultValue("20") @FormParam("limit") String limit){
		UserTalks st = new UserTalks();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st;
		}
		Integer userid = accountInfo.getInteger("id");
		List<Talk> result = UserService.getInstance().getTalks(userid,Integer.parseInt(from),Integer.parseInt(limit));
		if( result != null ){
			st.setData(result);
			st.setOk( true );
		}else{
			st.setOk(false);
			st.setMessage("获取数据异常");
		}
		return st;
	}
	
	/**
	 * 获取通知消息
	 * @param account
	 * @param userToken
	 * @param from
	 * @return
	 */
	@POST
	@Path("/{account}/notice")
	@Produces(MediaType.APPLICATION_JSON)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public String getNotice(
			@PathParam("account") String account,
			@FormParam("token") String userToken){
		GeneralJSONResult st = new GeneralJSONResult();
		JSONObject accountInfo = ApiUtils.checkAndGetUserInfo(userToken, account);
		if( accountInfo == null ){
			st.setOk(false);
			st.setMessage("invalid token");
			return st.toString();
		}
		Integer userid = accountInfo.getInteger("id");
		
		List<String> result = RedisService.getInstance().getNotice(String.valueOf(userid));
		if( result != null ){
			st.setData( (JSON)JSONArray.toJSON(result) );
			st.setOk( true );
		}else{
			st.setOk(false);
			st.setMessage("获取数据异常");
		}
		return st.toString();
	}

}